package com.cloud.system.api.web;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.cloud.system.api.bean.*;
import com.cloud.system.api.entity.DynamicUnitExcel;
import com.cloud.system.api.entity.DynamicUnitExcelExport;
import com.cloud.system.api.entity.PowerBasis;
import com.cloud.system.common.utils.ExcelUtils;
import com.cloud.system.interfaces.FeignClientLawCase;
import com.github.pagehelper.PageInfo;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.cloud.system.api.entity.UnitInfo;
import com.cloud.system.api.service.SystemCacheService;
import com.cloud.system.api.service.UnitInfoService;
import com.cloud.system.common.consts.SystemConst;
import com.cloud.system.common.result.Quokka;
import com.cloud.system.common.result.SelectItem;
import com.cloud.system.common.utils.ExcelField;
import com.cloud.system.common.utils.ExcelHelper;

import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("system/api/unitinfo")
public class UnitInfoController {

    @Autowired
    private UnitInfoService unitInfoService;

    @Autowired
    private SystemCacheService systemCacheService;

    @Autowired
    private FeignClientLawCase feignClientLawCase;

    @RequestMapping("listtree")
    public Quokka listTree(long unitId, boolean isRoot, String isSupervise,boolean isScreen) {
        return new Quokka(true, unitInfoService.listUnitTree(unitId, isRoot, isSupervise ,isScreen));
    }

    @RequestMapping("search")
    public Quokka search(String name) {
        return new Quokka(true, unitInfoService.search(name));
    }

    /**
     * 根据id查找数据
     *
     * @param unitId
     * @return
     */
    @RequestMapping("load")
    public Quokka load(long unitId) {
        return new Quokka(true, unitInfoService.load(unitId));
    }

    /**
     * 保存或更新机构信息
     *
     * @param info
     * @return
     */
    @RequestMapping("saveupdate")
    public Quokka saveUpdate(@RequestBody UnitInfo info) {
        return new Quokka(true, unitInfoService.saveUpdate(info));
    }

    /**
     * 删除组织机构
     *
     * @param unitId
     * @return
     */
    @RequestMapping("delete")
    public Quokka delete(long unitId) {
        return new Quokka(true, unitInfoService.delete(unitId));
    }

    /**
     * 加载编辑界面所需字典项目
     *
     * @return
     */
    @GetMapping("dict")
    public Quokka loadDicts(int sysId) {
        Quokka qk = new Quokka(true);
        Map<String, List<SelectItem>> map = new HashMap<String, List<SelectItem>>();
        map.put("entrustTypes", systemCacheService.loadSelectItem(SystemConst.UNIT_ENTRUST_TYPE));// 委托方式
        map.put("superviseUnitLevel", systemCacheService.loadSelectItem(SystemConst.SUPERVISE_UNIT_LEVEL));// 委托方式
        map.put("superviseUnitType", systemCacheService.loadSelectItem(SystemConst.SUPERVISE_UNIT_TYPE));
        map.put("entrustNatureTypes", systemCacheService.loadSelectItem(SystemConst.UNIT_ENTRUST_NATURE_TYPE));// 受委托组织性质
        map.put("unitNatureTypes", systemCacheService.loadSelectItem(SystemConst.UNIT_NATURE_TYPE));// 部门性质
        map.put("superviseUnitNatureTypes", systemCacheService.loadSelectItem(SystemConst.SUPERVISE_UNIT_NATURE_TYPE));// 部门性质
        map.put("unitLevels", systemCacheService.loadSelectItem(SystemConst.UNIT_LEVEL));// 部门层级
        map.put("domains", systemCacheService.loadSelectItem(SystemConst.UNIT_DOMAIN));// 所属领域
        map.put("manubriumLevels", systemCacheService.loadSelectItem(SystemConst.UNIT_MANUBRIUM_LEVEL));// 垂管层级
        map.put("subjectTypes", systemCacheService.loadSelectItem(SystemConst.UNIT_SUBJECT_TYPE));// 主体类别
        map.put("unitTypes", systemCacheService.loadSelectItem(SystemConst.UNIT_TYPE));// 执法机关类别
        map.put("powerTypes", systemCacheService.loadSelectItem(SystemConst.POWER_TYPES));// 职权类别
        map.put("powerCriminalTypes", systemCacheService.loadSelectItem(SystemConst.POWER_CRIMINAL_TYPES));// 是否涉刑
        map.put("powerStateTypes", systemCacheService.loadSelectItem(SystemConst.POWER_STATE_TYPES));// 职权状态
        map.put("powerPublicTypes", systemCacheService.loadSelectItem(SystemConst.POWER_PUBLIC_TYPES));// 是否公开
        map.put("powerLevelTypes", systemCacheService.loadSelectItem(SystemConst.POWER_LEVEL_TYPES));// 是否公开
        qk.setData(map);
        return qk;
    }

    @GetMapping("loadseniorsubject")
    public Quokka listSubject(long unitId) {
        Quokka qk = new Quokka(true);
        UnitInfo unitInfo = unitInfoService.load(unitId);
        qk.setData(unitInfoService.loadSeniorSubject(unitInfo));
        return qk;
    }

    /**
     * 下载数据导入模板
     *
     * @return
     * @throws Exception
     */
    @GetMapping("template")
    public ResponseEntity<byte[]> downloadTemplate(int uploadType) throws Exception {
        String name = "";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        switch (uploadType){
            case 0:
                name = "template/unit.template.xlsx";
                break;
            case 1:
                name = "template/power.template.xlsx";
                break;
        }
        InputStream in = this.getClass().getClassLoader().getResourceAsStream(name);
        return new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.OK);
    }

    /**
     * 解析上传的导入模板
     *
     * @param file
     * @return
     */
    @PostMapping("analyse")
    public Quokka analyseImportFile(MultipartFile file, int uploadType) throws Exception {
        Quokka quokka = new Quokka(true);
        switch (uploadType) {
            case 0:
                List<UnitImportBean> units = ExcelHelper.xlsx2List(file.getInputStream(),
                        new String[]{"unitName", "shortName", "socialCreditCode", "representiveName", "officeTel",
                                "postalCode", "fax", "unitAddress", "unitNatureName", "unitLevelName", "manubriumLevelName",
                                "manubriumName"},
                        UnitImportBean.class);
                Map<String, List<UnitImportBean>> analyseResult = unitInfoService.analyseImportFile(units);
                quokka.setData(analyseResult);
                break;
            case 1:
                List<PowerImportBean> unitPowers = ExcelHelper.xlsx2List(file.getInputStream(),
                        new String[]{"powerName", "powerTypeName", "isCriminal", "powerStateName", "isPublics"},
                        PowerImportBean.class);
                Map<String, List<PowerImportBean>> powerResult = unitInfoService.powerImportFile(unitPowers);
                quokka.setData(powerResult);
                break;
        }

        return quokka;
    }

    /**
     * 下级机构数据导入
     *
     * @param unitId
     * @return
     */
    @PostMapping("import")
    public Quokka importUnits(Long unitId, @RequestBody List<UnitInfo> units) {
        return new Quokka(true, unitInfoService.importUnits(unitId, units));
    }

    /**
     * 职权数据导入
     *
     * @param unitId
     * @param unitName
     * @param unitPowers
     * @return
     */
    @PostMapping("importpower")
    public Quokka importPower(Long unitId, String unitName, @RequestBody List<PowerImportBean> unitPowers){
        return new Quokka(true, unitInfoService.importPower(unitId, unitName, unitPowers));
    }

    @PostMapping("downloaderror")
    public ResponseEntity<byte[]> downloadError(@RequestBody List<UnitImportBean> units) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        List<ExcelField> fields = new ArrayList<ExcelField>();
        fields.add(new ExcelField("机关全称", "unitName"));
        fields.add(new ExcelField("机关简称", "shortName"));
        fields.add(new ExcelField("统一社会信息代码", "socialCreditCode"));
        fields.add(new ExcelField("法人代表", "representiveName"));
        fields.add(new ExcelField("联系电话", "officeTel"));
        fields.add(new ExcelField("邮政编码", "postalCode"));
        fields.add(new ExcelField("传真", "fax"));
        fields.add(new ExcelField("地址", "unitAddress"));
        fields.add(new ExcelField("部门性质", "unitNatureName"));
        fields.add(new ExcelField("机关层级", "unitLevelName"));
        fields.add(new ExcelField("垂管层级", "manubriumLevelName"));
        fields.add(new ExcelField("垂管部门全称", "manubriumName"));
        fields.add(new ExcelField("错误信息", "errorMsg"));
        ByteArrayOutputStream bos = (ByteArrayOutputStream) ExcelHelper.list2Xlsx(units, "机构导入错误数据", "", fields,
                UnitImportBean.class);
        return new ResponseEntity<byte[]>(bos.toByteArray(), headers, HttpStatus.OK);
    }

    /**
     * 获取下级机关
     *
     * @param unitId
     * @return
     */
    @GetMapping("children")
    public Quokka listChildren(Long unitId) {
        return new Quokka(true, unitInfoService.loadChildren(unitId));
    }

    /**
     * 机构重排序
     *
     * @param unitInfo
     * @return
     */
    @PostMapping("reorder")
    public Quokka reorderUnit(@RequestBody List<UnitInfo> unitInfo) {
        return new Quokka(true, unitInfoService.reorderUnit(unitInfo));
    }

    /**
     * 查询部门职权
     *
     * @param unitPowerCriteriaBean
     * @return
     */
    @PostMapping("getUnitPowersByID")
    public Quokka getUnitPowersByID(@RequestBody UnitPowerCriteriaBean unitPowerCriteriaBean) {
        return new Quokka(true, unitInfoService.getUnitPowersByID(unitPowerCriteriaBean));
    }

    /**
     * 查询部门许可
     *
     * @param unitPowerCriteriaBean
     * @return
     */
    @PostMapping("getUnitPermitByID")
    public Quokka getUnitPermitByID(@RequestBody UnitPowerCriteriaBean unitPowerCriteriaBean) {
        return new Quokka(true, unitInfoService.getUnitPermitByID(unitPowerCriteriaBean));
    }

    /**
     * 查询部门监管
     *
     * @param unitPowerCriteriaBean
     * @return
     */
    @PostMapping("getUnitInspectByID")
    public Quokka getUnitInspectByID(@RequestBody UnitPowerCriteriaBean unitPowerCriteriaBean) {
        return new Quokka(true, unitInfoService.getUnitInspectByID(unitPowerCriteriaBean));
    }

    /**
     * 查询部门监管
     *
     * @param unitPowerCriteriaBean
     * @return
     */
    @PostMapping("getUnitSuperviseByID")
    public Quokka getUnitSuperviseByID(@RequestBody UnitPowerCriteriaBean unitPowerCriteriaBean) {
        return new Quokka(true, unitInfoService.getUnitSuperviseByID(unitPowerCriteriaBean));
    }


    /**
     * 查询部门职权、许可、检查事项、监管的数量
     *
     * @param unitId
     * @return
     */
    @GetMapping("getUnitStatData")
    public Quokka getUnitStatData(Long unitId) {
        return new Quokka(true, unitInfoService.getUnitStatData(unitId));
    }

    /**
     * 分页查询部门信息
     *
     * @param criteria
     * @return
     */
    @RequestMapping("listUnitPage")
    public Quokka listUnitPage(@RequestBody UnitCriteriaBean criteria) {
        return new Quokka(true, unitInfoService.listUnitPage(criteria));
    }

    /**
     * 部门级别统计
     *
     * @return
     */
    @RequestMapping("getUnitLevelStat")
    public Quokka getUnitLevelStat(Integer isSupervise, Long unitID) {
        return new Quokka(true, unitInfoService.getUnitLevelStat(isSupervise, unitID));
    }

    /**
     * 监督部门级别统计
     *
     * @return
     */
    @RequestMapping("getSupUnitLevelStat")
    public Quokka getSupUnitLevelStat(Long unitID) {
        return new Quokka(true, unitInfoService.getSupUnitLevelStat(unitID));
    }


    /**
     * 监督部门区域内部门数量
     *
     * @return
     */
    @RequestMapping("getUnitCount")
    public Quokka getUnitCount(Long unitID, Integer isSupervise) {
        return new Quokka(true, unitInfoService.getUnitCount(unitID, isSupervise));
    }

    /**
     * 内设监督机构级别统计
     *
     * @return
     */
    @RequestMapping("getInnerSupUnitLevelStat")
    public Quokka getInnerSupUnitLevelStat(Long unitID) {
        return new Quokka(true, unitInfoService.getInnerSupUnitLevelStat(unitID));
    }

    /**
     * 部门性质统计
     *
     * @return
     */
    @RequestMapping("getUnitNatureStat")
    public Quokka getUnitNatureStat(Integer isSupervise, Long unitID) {
        return new Quokka(true, unitInfoService.getUnitNatureStat(isSupervise, unitID));
    }

    /**
     * 部门区域统计
     *
     * @return
     */
    @RequestMapping("getUnitAreaStat")
    public Quokka getUnitAreaStat(Integer isSupervise, Long unitID) {
        return new Quokka(true, unitInfoService.getUnitAreaStat(isSupervise, unitID));
    }

    /**
     * 主体类别统计
     *
     * @return
     */
    @RequestMapping("getLawSubjectStat")
    public Quokka getLawSubjectStat(Long unitID) {
        return new Quokka(true, unitInfoService.getLawSubjectStat(unitID));
    }

    /**
     * 委托机构方式统计
     *
     * @return
     */
    @RequestMapping("getEntrustUnitStat")
    public Quokka getEntrustUnitStat(Long unitID) {
        return new Quokka(true, unitInfoService.getEntrustUnitStat(unitID));
    }

    /**
     * 委托机构性质统计
     *
     * @return
     */
    @RequestMapping("getEntrustNatureStat")
    public Quokka getEntrustNatureStat(Long unitID) {
        return new Quokka(true, unitInfoService.getEntrustNatureStat(unitID));
    }


    /**
     * 区域信息自动补全
     *
     * @param value
     * @return
     */
    @RequestMapping("loadArea")
    public Quokka loadArea(String value) {
        return new Quokka(true, unitInfoService.loadArea(value));
    }


    /**
     * 查询部门是否包含子部门或人员
     *
     * @param isSupervise
     * @return
     */
    @RequestMapping("checkContainChild")
    public Quokka checkContainChild(Long unitId, Integer isSupervise) {
        return new Quokka(true, unitInfoService.checkContainChild(unitId, isSupervise));
    }


    @RequestMapping("adjust")
    public Quokka adjust(@RequestBody HumanUnitAdjustBean bean) {
        unitInfoService.adjust(bean);
        return new Quokka(true);
    }


    @RequestMapping("confirm")
    public Quokka confirm(long unitId) {
        return new Quokka(true, unitInfoService.confirm(unitId));
    }

    /**
     * 批量操作unit_domain
     *
     * @return
     */
    @RequestMapping("setUnitDomainValues")
    public Quokka setUnitDomainValues () {
        return new Quokka(true, unitInfoService.setUnitDomainValues());
    }

    /**
     * 批量操作unit_domain
     *
     * @return
     */
    @RequestMapping("setUnitDomainValue")
    public Quokka setUnitDomainValue () {
        return new Quokka(true, unitInfoService.setUnitDomainValue());
    }
    /**
     * 批量操作 unit_power -临时表
     */
    @RequestMapping(value = "setUnitPowerValuesTem", method = RequestMethod.POST)
    public Quokka setUnitPowerValuesTem (MultipartFile file){
        return new Quokka(true, unitInfoService.setUnitPowerValuesTem(file));
    }


    /**
     * 批量操作 unit_power
     */
    @RequestMapping(value = "setUnitPowerValues", method = RequestMethod.POST)
    public Quokka setUnitPowerValues () {
        return new Quokka(true, unitInfoService.setUnitPowerValues());
    }

    /**
     * 批量操作 unit_info
     */
    @RequestMapping(value = "setUnitInfoValues", method = RequestMethod.POST)
    public Quokka setUnitInfoValues (MultipartFile file){
        return new Quokka(true, unitInfoService.setUnitInfoValues(file));
    }

    /**
     * 更新保存职权依据
     * @param basisList
     * @return
     */
    @RequestMapping("saveupdatepowerbasis")
    public Quokka saveUpdatePowerBasis (@RequestBody List<PowerBasis> basisList) {
        return new Quokka(true, unitInfoService.saveUpdatePowerBasis(basisList));
    }

    /**
     * 删除职权依据
     * @param basisList
     * @return
     */
    @RequestMapping("deletepowerbasis")
    public Quokka deletePowerBasisById (@RequestBody List<PowerBasis> basisList) {
        return new Quokka(true, unitInfoService.deletePowerBasisById(basisList));
    }

    /**
     *
     *
     * @return
     */
    @RequestMapping("saveDicRegion")
    public Quokka saveDicRegion(@RequestBody String regionJson) {
        return new Quokka(true, unitInfoService.saveDicRegion(regionJson));
    }

    /**
     * 加载地址
     * @return
     */
    @RequestMapping("loadaddress")
    public Quokka loadAddress() {
        return new Quokka(true, unitInfoService.loadAddress());
    }

    /**
     *新增职权
     * @param unitPowerBean
     * @return
     */
    @RequestMapping("addPowerBasis")
    public Quokka addPowerBasis(@RequestBody UnitPowerBean unitPowerBean) {
        return new Quokka(true, unitInfoService.addPowerBasis(unitPowerBean));
    }

    /**
     * 删除职权
     * @param powerId
     * @return
     */
    @RequestMapping("deletepower")
    public Quokka deletePowerById(Integer powerId) {
        return new Quokka(true, unitInfoService.deletePowerById(powerId));
    }

    @PostMapping("searchlawcause")
    public Quokka searchLawCause(@RequestBody LawCauseSearchCriteria criteria){
        PageInfo<LawCauseItem> pageInfo = feignClientLawCase.lawCausePagination(criteria);
        return new Quokka(true, pageInfo);
    }

    /**
     * 加载职权
     * @param powerId
     * @return
     */
    @RequestMapping("loadpowerbyid")
    public Quokka loadPowerById(Integer powerId) {
        return new Quokka(true,unitInfoService.loadPowerById(powerId));
    }


    /**
     * subject——id
     */
    @RequestMapping("setSubjectIdValue")
    public Quokka setSubjectIdValue() {
        return new Quokka(true,unitInfoService.setSubjectIdValue());
    }

    /**
     * subject——id
     */
    @RequestMapping("setSubjectIdValues")
    public Quokka setSubjectIdValues() {
        return new Quokka(true,unitInfoService.setSubjectIdValues());
    }

    /**
     * 行政处罚默认地址
     * @param id
     * @return
     */
    @RequestMapping("loadareaid")
    public Quokka loadAreaId(Long id) {
        return new Quokka(true,unitInfoService.loadAreaId(id));
    }

    /**
     * 0926页面改版 - 执法动态接口
     * 行政检查 一般程序 简易程序 行政强制
     */
    @RequestMapping("getLawDynamicsInfo")
    public Quokka getLawDynamicsInfo() {
        return new Quokka(true,unitInfoService.getLawDynamicsInfo());
    }

    /**
     *  部门信息
     */
    @RequestMapping("getDepartmentInfo")
    public Quokka getDepartmentInfo() {
        return new Quokka(true,unitInfoService.getDepartmentInfo());
    }

    /**
     * 数据统计 统计单位下一共有多少人员，职权数 ，职权（行政处罚 行政强制）数，行政职权（处罚、强制）关联数 检查事项 监管事项 行政处罚录入数
     */
    @RequestMapping("getDynamicUnitInfo")
    public Quokka getDynamicUnitInfo(@RequestBody DynamicUnitExcel dynamicUnitExcel) throws Exception {
        return new Quokka(true,unitInfoService.getDynamicUnitInfo(dynamicUnitExcel));
    }

    /**
     * 考核附件下载
     * @param response
     * @param dynamicUnitExcel
     * @return
     */
    @RequestMapping(value = "/exportExcel",produces = {"application/vnd.ms-excel;charset=UTF-8"})
    public ResponseEntity<byte[]> export(HttpServletResponse response,@RequestBody DynamicUnitExcel dynamicUnitExcel) {
        return unitInfoService.exportExcel(response, dynamicUnitExcel);
    }

    /**
     * 账户管理信息分页加载
     * @param humanInfoCriteriaBean
     * @return
     */
    @RequestMapping("listhumaninfopage")
    public Quokka listHumanInfoPage(@RequestBody HumanInfoCriteriaBean humanInfoCriteriaBean) {
        return new Quokka(true,unitInfoService.listHumanInfoPage(humanInfoCriteriaBean));
    }

    /**
     * 导入南宁市结案表数据
     */
    @RequestMapping("importClosingTable")
    public Quokka importClosingTable (MultipartFile file){
        return new Quokka(true, unitInfoService.importClosingTable(file));
    }
    /**
     * 根据登录人所在区域加载地址
     * @return
     */
    @RequestMapping("loadAddressByUser")
    public Quokka loadAddressByUser() {
        return new Quokka(true, unitInfoService.loadAddressByUser());
    }
}
